'use strict';
const db = uniCloud.database();
const businessInfoDBName = 'zhy_business_info';
const orderProfitSharingDBName = 'zhy_order_profitsharing';
const orderDBName = 'zhy_order';
const business_bind_receiverDBName = 'zhy_business_bind_receiver';
const wxconfig = require('./wxconfig.js');
const WxPay = require('wechatpay-node-v3');
const fs = require('fs');
const request = require('superagent');
const pay = new WxPay({
	appid: wxconfig.appid,
	mchid: wxconfig.mchid,
	publicKey: fs.readFileSync(__dirname + '/cert/apiclient_cert.pem'), // 公钥
	privateKey: fs.readFileSync(__dirname + '/cert/apiclient_key.pem'), // 秘钥
});

exports.main = async (event, context) => {
	//event为客户端上传的参数
	console.log('event : ', event)
	console.log('context : ', context.CLIENTIP)
	if (event.type == 1) {
		/* event示例
		{code:'xxxxxxxxx'}
		*/
		// 获取opneid
		return getOpenid(event, context)
	} else if (event.type == 2) {
		/* event示例
		{
			orderId: orderId,
			openid: uni.getStorageSync(app.globalData.session.userKey),
			amount: price,
			amountFen: this.$mytools.regYuanToFen(price, 100),
			title: '商户充值',
			type: 2, //统一下单--直连支付模式，如：商户充值--下单
			remark: '备注:商户充值',
		}
		*/
		// 商户充值:统一下单接口
		return merchantRecharge(event, context)
	} else if (event.type == 3) {
		/*
		{
			// user用户 tx提现
			out_batch_no: this.$idGenerator.createUniqueId('usertx'),
			batch_name: '用户提现',
			batch_remark: '感谢参与霸王补贴',
			total_amount: total_amount, //单位：分
			total_num: 1,
			transfer_detail_list: [{
				out_detail_no: this.$idGenerator.createUniqueId('usertx'),
				transfer_amount: total_amount,
				transfer_remark: this.$mytools.formatTimestampToDateStr(new Date().getTime()) +
					'日一次性提现',
				openid: uni.getStorageSync(app.globalData.session.userKey),
				user_name: null //>2000元才必须
			}]
		}
		*/
		// 用户提现
		return userWithdrawal(event, context)
	} else if (event.type == 4) {
		/*
		{
			orderId: orderId,
			openid: uni.getStorageSync(app.globalData.session.userKey),
			amount: price,
			amountFen: this.$mytools.regYuanToFen(price, 100),
			title: '商户充值',
			type: 4, //服务商支付模式--下单
			remark: '备注:商户充值',
		}
		*/
		// 统一下单:分账，聚合支付下单，开启分账
		return partnerUnifiedorder(event, context)
	} else if (event.type == 5) {
		/*
		{
			description: profitSharingParam.description, // 分账描述
			amountFen: params.amountFen, // 分账金额，单位：分
			orderId: profitSharingParam.orderId, // 商户分账单号，并非商户的订单号，分账单号=ps+orderId
			offlineBusinessId: profitSharingParam.offlineBusinessId // 商户id
		}
		*/
		// 发起分账请求
		return partnerProfitSharing(event, context)
	} else if (event.type == 6) {
		/*
		{
			offlineBusinessId: businessId
		}
		*/
		// 添加分账接收方。分帐前比做！
		return profitsharingaddreceiver(event, context)
	}
	console.log('类型不规范');
	return '';
}

// 获取openid
async function getOpenid(event, context) {
	let appid = wxconfig.appid; //在花一小程序appid
	let secret = wxconfig.appSecret; //在花一小程序
	let url =
		"https://api.weixin.qq.com/sns/jscode2session?appid=" +
		appid +
		"&secret=" +
		secret +
		"&js_code=" +
		event.code +
		"&grant_type=authorization_code";
	let res = await uniCloud.httpclient.request(
		url, // 请求路径,
		{
			dataType: "json"
		}
	);
	let openid = res.data.openid
	return openid
}
// 统一下单：不分账，如：商户充值
async function merchantRecharge(event, context) {
	console.log(JSON.stringify(pay));
	console.log(context.CLIENTIP);
	const params = {
		appid: pay.appid,
		mchid: pay.mchid,
		description: event.title,
		out_trade_no: event.orderId,
		notify_url: wxconfig.notifyUrl,
		amount: {
			total: event.amountFen,
		},
		payer: {
			openid: event.openid,
		},
		scene_info: {
			payer_client_ip: context.CLIENTIP,
		},
	};
	console.log(params);
	const result = await pay.transactions_jsapi(params);
	console.log(JSON.stringify(result));
	if (result != null && result.status == 200) {
		// success
		console.log('下单成功');
		/*
		#   {
		#     appId: 'appid',
		#     timeStamp: '1609918952',
		#     nonceStr: 'y8aw9vrmx8c',
		#     package: 'prepay_id=wx0615423208772665709493edbb4b330000',
		#     signType: 'RSA',
		#     paySign: 'JnFXsT4VNzlcamtmgOHhziw7JqdnUS9qJ5W6vmAluk3Q2nska7rxYB4hvcl0BTFAB1PBEnHEhCsUbs5zKPEig=='
		#   }
		*/
		// 保存订单
		event.pay_success_status = 1
		event.amount = event.amountFen
		event.remark = event.remark
		event.status = 0
		event.clientIP = context.CLIENTIP
		event.trade_type = 'JSAPI'
		event.order_time = result.data.timeStamp
		event.pay_time = null
		event.pay_success_status = 1
		event.order_plat = 'mp-weixin'
		event.profit_sharing = 0
		saveOrder(event)
		return result.data;
	} else {
		// 下单失败
		event.pay_success_status = 1
		event.amount = event.amountFen
		event.remark = event.remark
		event.status = 0
		event.clientIP = context.CLIENTIP
		event.trade_type = 'JSAPI'
		event.order_time = parseInt(new Date().getTime() / 1000)
		event.pay_time = null
		event.pay_success_status = 0
		event.pay_fail_reason = toString(JSON.parse(result.error).message)
		event.order_plat = 'mp-weixin'
		event.profit_sharing = 0
		saveOrder(event)
		return null
	}
}
// 普通用户：提现到零钱
async function userWithdrawal(event, context) {
	// const certificates = await pay.get_certificates("APIv3密钥");
	const certificates = await pay.get_certificates(wxconfig.mchKeyV2);
	console.log(JSON.stringify(certificates));
	const certificate = certificates.pop();
	let transfer_detail_list = event.transfer_detail_list
	for (let i = 0; i < transfer_detail_list.length; i++) {
		// 有真实姓名，则赋值
		let detail = transfer_detail_list[i]
		if (detail.user_name != undefined && detail.user_name != null && detail.user_name != '') {
			detail.user_name = pay.publicEncrypt(detail.user_name,
				Buffer.from(certificate.publicKey))
			transfer_detail_list[i] = detail
		}
	}

	const res = await pay.batches_transfer({
		out_batch_no: event.out_batch_no,
		batch_name: event.batch_name,
		batch_remark: event.batch_remark,
		total_amount: event.total_amount, // 单位：分
		total_num: event.total_num, //transfer_detail_list长度
		wx_serial_no: certificate.serial_no, // 当你需要传user_name时 需要传当前参数
		transfer_detail_list: transfer_detail_list
		/* transfer_detail_list: [{
			out_detail_no: 'x23zy545Bd5436',
			transfer_amount: 200000,
			transfer_remark: '2020年4月报销',
			openid: event.openid,
			//明细转账金额 >= 2,000元，收款用户姓名必填；
			// user_name: pay.publicEncrypt('张三', Buffer.from(certificate.publicKey)),
		}], */
	});
	console.log('提现结果');
	console.log(JSON.stringify(res));
	return res
	/*
	// 微信批次单号查询批次单API
	const res = await pay.query_batches_transfer_list_wx()
	// 微信明细单号查询明细单API
	const res = await pay.query_batches_transfer_detail_wx()
	// 商家批次单号查询批次单API
	const res = await pay.query_batches_transfer_list()
	// 商家明细单号查询明细单API
	const res = await pay.query_batches_transfer_detail()
	*/
}

// 保存订单到zhy_order表中
async function saveOrder(order) {
	if (order == null || order == undefined || order == '' || JSON.stringify(order) == '{}') {
		return {
			errSubject: 'order_param_lack',
			errCode: 0,
			errMsg: '订单信息不全'
		}
	}
	// 查询订单的transaction_id
	let orderResult = await orderquery(order.orderId)
	let orderInfo = {
		// add
		operateType: 1,
		// 字段
		openid: order.openid,
		orderId: order.orderId,
		title: order.title,
		amount: order.amountFen,
		type: order.type,
		trade_type: order.trade_type,
		remark: order.remark,
		order_time: order.order_time,
		pay_time: order.pay_time,
		status: order.status,
		clientIP: order.clientIP,
		pay_success_status: order.pay_success_status,
		pay_fail_reason: order.pay_fail_reason,
		order_plat: 'mp-weixin',
		profit_sharing: order.profit_sharing,
		transaction_id: orderResult.transaction_id,
	}
	uniCloud.callFunction({
		name: 'zhy-order',
		data: orderInfo
	})
}

//========================================分账相关=========================================//
// 获取微信订单号
async function getAndSetTransactionId(orderId) {
	let transationId = ''
	if (orderId == null || orderId == undefined || orderId == '') {
		return transationId
	}
	let orderResult = await db.collection(orderDBName).where({
		orderId: orderId
	}).limit(1).get()
	if (orderResult == null || orderResult.data == null || orderResult.data.length == 0) {
		// 无此订单
		return transationId
	} else {
		let order = orderResult.data[0]
		if (order.transaction_id == null || order.transaction_id == '') {
			// 未赋值，去查询
			let wxOrder = await orderquery(orderId)
			transationId = wxOrder.transaction_id
			// 去赋值
			db.collection(orderDBName).doc(order._id).update({
				transaction_id: transationId
			})
		} else {
			//直接返回
			transationId = order.transaction_id
		}
	}
	return transationId
}

// 查询订单
async function orderquery(orderId) {
	const result = await pay.query({
		out_trade_no: orderId
	});
	console.log('微信订单查询结果:' + JSON.stringify(result));
	return result;
	/*
	{
	    status: 200,
	    appid: 'appid',
	    attach: '',
	    mchid: '商户号',
	    out_trade_no: '1609899981750',
	    payer: {},
	    promotion_detail: [],
	    trade_state: 'CLOSED',
	    trade_state_desc: '订单已关闭'
	  }
	*/
}

// 统一下单：分账
async function partnerUnifiedorder(event, context) {
	console.log(JSON.stringify(pay));
	console.log(context.CLIENTIP);
	const params = {
		appid: pay.appid,
		mchid: pay.mchid,
		description: event.title,
		out_trade_no: event.orderId,
		notify_url: wxconfig.notifyUrl,
		amount: {
			total: event.amountFen,
		},
		payer: {
			openid: event.openid,
		},
		scene_info: {
			payer_client_ip: context.CLIENTIP,
		},
		settle_info: {
			profit_sharing: true // 开启分账
		}
	};
	console.log(params);
	const result = await pay.transactions_jsapi(params);
	console.log(JSON.stringify(result));
	if (result != null && result.status == 200) {
		// success
		console.log('下单成功');
		/*
		#   {
		#     appId: 'appid',
		#     timeStamp: '1609918952',
		#     nonceStr: 'y8aw9vrmx8c',
		#     package: 'prepay_id=wx0615423208772665709493edbb4b330000',
		#     signType: 'RSA',
		#     paySign: 'JnFXsT4VNzlcamtmgOHhziw7JqdnUS9qJ5W6vmAluk3Q2nska7rxYB4hvcl0BTFAB1PBEnHEhCsUbs5zKPEig=='
		#   }
		*/
		// 保存订单
		event.pay_success_status = 1
		event.amount = event.amountFen
		event.remark = event.remark
		event.status = 0
		event.clientIP = context.CLIENTIP
		event.trade_type = 'JSAPI'
		event.order_time = result.data.timeStamp
		event.pay_time = null
		event.pay_success_status = 1
		event.order_plat = 'mp-weixin'
		event.profit_sharing = 1
		saveOrder(event)
		return result.data;
	} else {
		// 下单失败
		event.pay_success_status = 1
		event.amount = event.amountFen
		event.remark = event.remark
		event.status = 0
		event.clientIP = context.CLIENTIP
		event.trade_type = 'JSAPI'
		event.order_time = parseInt(new Date().getTime() / 1000)
		event.pay_time = null
		event.pay_success_status = 0
		event.pay_fail_reason = toString(JSON.parse(result.error).message)
		event.order_plat = 'mp-weixin'
		event.profit_sharing = 1
		saveOrder(event)
		return null
	}
}

// 发起分账请求.out_order_no生成格式：ps+商户订单号(orderId)
async function partnerProfitSharing(event, context) {
	let businessId = event.offlineBusinessId
	// 查询出business信息
	let businessInfo = await getBusinessInfo(businessId)
	if (businessInfo == null) {
		console.log('无此商户：' + businessId);
		return null
	} else {
		if (businessInfo.addWXpayReceiverSuccess === 0) {
			await profitsharingaddreceiver({
				offlineBusinessId: businessId
			})
		}
	}
	// businessInfo

	console.log(JSON.stringify(pay));
	console.log(context.CLIENTIP);
	// 查询微信订单号transaction_id
	// 1.调用微信接口查询:let wxOrder = await orderquery(event.orderId)
	// 2.zhy_order表的transaction_id字段
	let wx_transaction_id = await getAndSetTransactionId(event.orderId)
	const profitsharingResult = await pay.create_profitsharing_orders({
		transaction_id: wx_transaction_id, //微信支付订单号 ，待传值
		out_order_no: 'ps' + event.orderId, //商户分账单号：服务商系统内部的分账单号  自己创建的订单号
		receivers: [{
			type: 'MERCHANT_ID', //
			account: businessInfo.bs_weixin_no, //收钱的商户id
			// name: pay.publicEncrypt('张三', certificate.publicKey),
			amount: event.amountFen, // 分账金额，单位为分
			description: event.description, //分账的原因描述，分账账单中需要体现
		}, ],
		//是否解冻剩余未分资金：1、如果为true，该笔订单剩余未分账的金额会解冻回分账方商户；2、如果为false，该笔订单剩余未分账的金额不会解冻回分账方商户，可以对该笔订单再次进行分账。
		unfreeze_unsplit: true,
		// wx_serial_no: certificate.serial_no, // 当你需要传name时 需要传当前参数
	});
	// 其余分账操作：https://github.com/klover2/wechatpay-node-v3-ts/blob/master/docs/profitsharing.md
	// 分账常见问题：https://developers.weixin.qq.com/community/pay/doc/000284823e8460aada68dacca5b008
	// 查询分账结果
	// const res = await pay.query_profitsharing_orders('4208450740201411110007820472', 'P20150806125346');
	// https://api.mch.weixin.qq.com/v3/profitsharing/orders/P20150806125346?transaction_id=4208450740201411110007820472
	console.log(JSON.stringify(profitsharingResult));
	// profitsharingResult.transaction_id = wx_transaction_id // 设置标识，便于查询
	// profitsharingResult.orderId = event.orderId // 设置标识，便于查询
	// profitsharingResult.profitsharing_type = 1 // 微信分账
	if (profitsharingResult != null && profitsharingResult.return_code === 'SUCCESS') {
		// success
		console.log('分账成功');
		// 保存分账
		saveProfitSharingOrder(inputParam, profitsharingResult, 1)
		return profitsharingResult;
	} else {
		// 下单失败
		saveProfitSharingOrder(inputParam, profitsharingResult, 0)
		return null
	}
}

// 添加分账接收方。商户入驻成功后添加接收方
async function profitsharingaddreceiver(event, context) {
	let businessId = event.offlineBusinessId
	// 查询出business信息
	let businessInfo = await getBusinessInfo(businessId)
	if (businessInfo == null) {
		console.log('无此商户：' + businessId);
		return null
	} else {
		if (businessInfo.addWXpayReceiverSuccess === 1) {
			// 已经成功添加收款方
			console.log(businessId + '已添加分账接收方，无需再次添加');
			return null
		}
	}
	let profitsharing_receivers_addParam = {
		appid: wxconfig.appid,
		type: 'MERCHANT_ID',
		account: businessInfo.bs_weixin_no, //接收方商户号
		// 分账接收方全称：分账接收方类型是MERCHANT_ID时，是商户全称（必传）；当商户是小微商户或个体户时，是开户人姓名
		// name: pay.publicEncrypt('张三', certificate.publicKey),// todo lxw 暂时不传，页面没有传参
		/*
		子商户与接收方的关系。
		本字段值为枚举：
		SERVICE_PROVIDER：服务商
		STORE：门店 
		STAFF：员工
		STORE_OWNER：店主
		PARTNER：合作伙伴
		HEADQUARTER：总部
		BRAND：品牌方
		DISTRIBUTOR：分销商
		USER：用户
		SUPPLIER：供应商
		CUSTOM：自定义
		*/
		relation_type: 'PARTNER',
		custom_relation: '合作伙伴',
	}
	const res = await pay.profitsharing_receivers_add(profitsharing_receivers_addParam);
	console.log('添加分账接收方结果');
	console.log(JSON.stringify(res));
	// 保存入库：1.zhy_business_bind_receiver 2.保存到商户表，标识是否成功即可
	if (res.return_code === 'SUCCESS') {
		//成功
		console.log('成功');
		db.collection(dbCollectionName).doc(businessInfo._id).update({
			addWXpayReceiverSuccess: 1
		});
		saveBindRecieverRecord(profitsharing_receivers_addParam, res, 1)
	} else {
		console.log('失败 ');
		db.collection(dbCollectionName).doc(businessInfo._id).update({
			addWXpayReceiverSuccess: 0,
			addWXpayReceiverFailReason: res.return_msg
		});
		saveBindRecieverRecord(profitsharing_receivers_addParam, res, 0)
	}
	return res
}

// 获取商户详细信息
async function getBusinessInfo(businessId) {
	if (businessId == undefined || businessId == '' || businessId == '') {
		return null
	}
	let bs = await db.collection(businessInfoDBName).where({
		offlineBusinessId: businessId
	}).limit(1).get()
	if (bs.data == null || bs.data.length == 0) {
		return null
	}
	return bs.data[0]
}

// 保存分账结果
function saveProfitSharingOrder(inputParam, outputParam, success) {
	let p = {
		profitsharing_type: 1,
		input_param: inputParam,
		output_param: outputParam,
		success: success,
		ps_time: new Date().getTime(),
		profitsharing_id: inputParam.out_order_no,
	}
	db.collection(orderProfitSharingDBName).add(p)
}

// 保存添加分账账户输入和结果
async function saveBindRecieverRecord(intput, output, sucess) {
	db.collection(business_bind_receiverDBName).add({
		bindType: 1,
		input_param: intput,
		output_param: output,
		success: success,
		addTime: parseInt(new Date().getTime() / 1000)
	})
}
//========================================分账相关=========================================//